package handler

import (
	"oa-system/internal/api/request"
	"oa-system/internal/model"
	"oa-system/internal/service"
	"oa-system/pkg/errors"
	"oa-system/pkg/response"
	"oa-system/pkg/utils"

	"github.com/gin-gonic/gin"
)

type MenuHandler struct {
	menuService service.MenuService
}

func NewMenuHandler(menuService service.MenuService) *MenuHandler {
	return &MenuHandler{
		menuService: menuService,
	}
}

// GetAllMenus godoc
// @Summary 获取菜单列表
// @Description 获取所有菜单信息，支持分页
// @Tags 菜单模块
// @Accept json
// @Produce json
// @Param page query int false "当前页码" default(1)
// @Param pageSize query int false "每页记录数" default(10)
// @Success 200 {object} response.Response{data=response.PageData{list=[]model.Menu,total=int}}
// @Router /menus [get]
func (h *MenuHandler) GetAllMenus(c *gin.Context) {
	var req request.MenuListRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, errors.NewBadRequestError("无效的请求参数", err))
		return
	}

	menus, total, err := h.menuService.GetAllMenus(req.Page, req.PageSize)
	if err != nil {
		response.Error(c, err)
		return
	}

	response.PageSuccess(c, menus, total, req.Page, req.PageSize)
}

// CreateMenu godoc
// @Summary 创建菜单
// @Description 创建新菜单
// @Tags 菜单模块
// @Accept json
// @Produce json
// @Param menu body request.CreateMenuRequest true "菜单信息"
// @Success 200 {object} response.Response{data=model.Menu}
// @Router /menus [post]
func (h *MenuHandler) CreateMenu(c *gin.Context) {
	var req request.CreateMenuRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, errors.NewBadRequestError("无效的请求参数", err))
		return
	}

	menu, err := h.menuService.CreateMenu(&req)
	if err != nil {
		response.Error(c, err)
		return
	}

	response.SuccessWithMessage(c, "菜单创建成功", menu)
}

// UpdateMenu godoc
// @Summary 更新菜单
// @Description 更新指定菜单信息
// @Tags 菜单模块
// @Accept json
// @Produce json
// @Param id path uint true "菜单ID"
// @Param menu body request.UpdateMenuRequest true "菜单信息"
// @Success 200 {object} response.Response{data=model.Menu}
// @Router /menus/{id} [put]
func (h *MenuHandler) UpdateMenu(c *gin.Context) {
	id, err := utils.ParseUintParam(c, "id")
	if err != nil {
		response.Error(c, errors.NewBadRequestError("无效的菜单ID", err))
		return
	}

	var req request.UpdateMenuRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, errors.NewBadRequestError("无效的请求参数", err))
		return
	}

	menu, err := h.menuService.UpdateMenu(id, &req)
	if err != nil {
		response.Error(c, err)
		return
	}

	response.SuccessWithMessage(c, "菜单更新成功", menu)
}

// DeleteMenu godoc
// @Summary 删除菜单
// @Description 删除指定菜单
// @Tags 菜单模块
// @Accept json
// @Produce json
// @Param id path uint true "菜单ID"
// @Success 200 {object} response.Response
// @Router /menus/{id} [delete]
func (h *MenuHandler) DeleteMenu(c *gin.Context) {
	id, err := utils.ParseUintParam(c, "id")
	if err != nil {
		response.Error(c, errors.NewBadRequestError("无效的菜单ID", err))
		return
	}

	if err := h.menuService.DeleteMenu(id); err != nil {
		response.Error(c, err)
		return
	}

	response.SuccessWithMessage(c, "菜单删除成功", nil)
}

// GetAllMenusWithRoles godoc
// @Summary 获取所有菜单及其角色信息
// @Description 获取所有菜单及其角色信息，支持分页
// @Tags 菜单模块
// @Accept json
// @Produce json
// @Param page query int false "当前页码" default(1)
// @Param pageSize query int false "每页记录数" default(10)
// @Success 200 {object} response.Response{data=response.PageData{list=[]model.Menu,total=int}}
// @Router /menus/menusWithRoles [get]
func (h *MenuHandler) GetAllMenusWithRoles(c *gin.Context) {
	var req request.MenuListRequest
	if err := c.ShouldBindQuery(&req); err != nil {
		response.Error(c, errors.NewBadRequestError("无效的请求参数", err))
		return
	}

	menus, total, err := h.menuService.GetAllMenusWithRoles(req.Page, req.PageSize)
	if err != nil {
		response.Error(c, err)
		return
	}

	response.PageSuccess(c, menus, total, req.Page, req.PageSize)
}

// GetUserMenus godoc
// @Summary 获取用户菜单
// @Description 获取指定用户的菜单及权限信息
// @Tags 菜单模块
// @Accept json
// @Produce json
// @Param user_id path uint true "用户ID"
// @Success 200 {object} response.Response{data=[]model.Menu}
// @Router /menus/getRoutes/{user_id} [get]
func (h *MenuHandler) GetUserMenus(c *gin.Context) {
	userID, exists := c.Get("userID")
	if !exists {
		response.Error(c, errors.NewBadRequestError("无效的用户ID", nil))
		return
	}

	menus, err := h.menuService.GetUserMenus(userID.(uint))
	if err != nil {
		response.Error(c, err)
		return
	}

	response.Success(c, menus)
}

// AddMenuPermissions godoc
// @Summary 添加菜单权限
// @Description 为指定菜单添加权限配置
// @Tags 菜单模块
// @Accept json
// @Produce json
// @Param id path uint true "菜单ID"
// @Param permissions body []model.Permission true "权限信息列表"
// @Success 200 {object} response.Response
// @Router /menus/permissions/{id} [post]
func (h *MenuHandler) AddMenuPermissions(c *gin.Context) {
	menuID, err := utils.ParseUintParam(c, "id")
	if err != nil {
		response.Error(c, errors.NewBadRequestError("无效的菜单ID", err))
		return
	}

	var req request.AddMenuPermissionsRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Error(c, errors.NewBadRequestError("无效的权限参数", err))
		return
	}

	// 转换请求数据为 model.Permission
	permissions := make([]model.Permission, len(req.Permissions))
	for i, p := range req.Permissions {
		permissions[i] = model.Permission{
			Code:        p.Code,
			Description: p.Description,
			RoleIDs:     p.RoleIDs,
		}
	}

	if err := h.menuService.AddMenuPermissions(menuID, permissions); err != nil {
		response.Error(c, err)
		return
	}

	response.SuccessWithMessage(c, "菜单权限添加成功", nil)
}

// GetMenuPermissions godoc
// @Summary 获取菜单权限
// @Description 获取指定菜单的权限配置
// @Tags 菜单模块
// @Accept json
// @Produce json
// @Param id path uint true "菜单ID"
// @Success 200 {object} response.Response{data=[]model.Permission}
// @Router /menus/permissions/{id} [get]
func (h *MenuHandler) GetMenuPermissions(c *gin.Context) {
	menuID, err := utils.ParseUintParam(c, "id")
	if err != nil {
		response.Error(c, errors.NewBadRequestError("无效的菜单ID", err))
		return
	}

	permissions, err := h.menuService.GetMenuPermissions(menuID)
	if err != nil {
		response.Error(c, err)
		return
	}

	response.Success(c, permissions)
}
